from fastapi import APIRouter, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordRequestForm
from datetime import timedelta, datetime
from app.models import User, UserRoleEnum
from app.auth import verify_password, create_access_token, get_password_hash
from app.dependencies import get_current_user
from pydantic import BaseModel, EmailStr, constr, Field, validator
from typing import Optional
import re

router = APIRouter(tags=["认证"])

# 密码强度验证
def validate_password_strength(password: str):
    if len(password) < 8:
        raise ValueError("密码长度至少8个字符")
    if not re.search(r"[A-Z]", password):
        raise ValueError("密码必须包含至少一个大写字母")
    if not re.search(r"[a-z]", password):
        raise ValueError("密码必须包含至少一个小写字母")
    if not re.search(r"\d", password):
        raise ValueError("密码必须包含至少一个数字")
    if not re.search(r"[!@#$%^&*(),.?\":{}|<>]", password):
        raise ValueError("密码必须包含至少一个特殊字符")

class Token(BaseModel):
    access_token: str
    token_type: str

class UserCreate(BaseModel):
    username: str = Field(..., min_length=3, max_length=50, pattern=r"^[a-zA-Z0-9_]+$")
    email: EmailStr
    password: str
    phone: str = Field(None, min_length=11, max_length=11)

    # 自定义验证器（如果需要更复杂的验证）
    @classmethod
    def validate_username(cls, v):
        if not re.match(r'^[a-zA-Z0-9_]+$', v):
            raise ValueError('用户名只能包含字母、数字和下划线')
        return  v

class UserResponse(BaseModel):
    id: int
    username: str
    email: str
    role: str
    is_active: bool
    head_image: Optional[str] = None
    phone: str
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None
    last_login: Optional[datetime] = None

    @validator('head_image', pre=True, allow_reuse=True)
    def make_absolute(cls, v):
        # v 可能是 None 或 "/static/avatar/7.png"
        if not v:
            return None
        # 拼成绝对路径
        return f"http://127.0.0.1:8000/static/{v}"

    class Config:
        orm_mode = True

@router.post("/token", response_model=Token)
async def login_for_access_token(form_data: OAuth2PasswordRequestForm = Depends()):
    """用户登录接口，获取访问令牌"""
    user = await User.filter(username=form_data.username).first()

    if not user:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="用户名或密码错误",
            headers={"WWW-Authenticate": "Bearer"},
        )

    if not verify_password(form_data.password, user.password_hash):
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="用户名或密码错误",
            headers={"WWW-Authenticate": "Bearer"},
        )

    access_token_expires = timedelta(minutes=30)
    access_token = create_access_token(
        data={"sub": str(user.id), "role": user.role},
        expires_delta=access_token_expires
    )

    return {"access_token": access_token, "token_type": "bearer"}

@router.post("/register", response_model=UserResponse)
async def register_user(user_data: UserCreate):
    """用户注册接口"""
    # 验证密码强度
    try:
        validate_password_strength(user_data.password)
    except ValueError as e:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=str(e),
        )

    existing_user = await User.filter(username=user_data.username).first()
    if existing_user:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="用户名已存在",
        )

    existing_email = await User.filter(email=user_data.email).first()
    if existing_email:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="邮箱已存在",
        )

    if user_data.phone:
        existing_phone = await User.filter(phone=user_data.phone).first()
        if existing_phone:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="手机号已存在",
            )

    user = await User.create(
        username=user_data.username,
        email=user_data.email,
        password_hash=get_password_hash(user_data.password),
        phone=user_data.phone,
        role=UserRoleEnum.CUSTOMER  # 使用枚举值而不是字符串
    )

    return user

@router.get("/users/me", response_model=UserResponse)
async def read_users_me(current_user: User = Depends(get_current_user)):
    """获取当前用户信息"""
    return current_user
